package cn.maxhou.t0002;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.lang.reflect.Proxy;

public class ValidationProxy {
    public static Object newInstance(Object target){
        return Proxy.newProxyInstance(
              target.getClass().getClassLoader(),
              target.getClass().getInterfaces(),
              new ValidationInvocationHandler(target)
        );
    }

    private static class ValidationInvocationHandler implements InvocationHandler {
        private final Object target;

        private ValidationInvocationHandler(Object target) {
            this.target = target;
        }

        @Override
        public Object invoke(Object proxy, Method method,Object[] args) throws Throwable {
            //获取接口上的方法信息
            Method[] methods=target.getClass().getInterfaces()[0].getMethods();
            for(Method m:methods){
                if(m.getName().equals(method.getName())&&
                m.getParameterCount()==args.length){
                    Parameter[] parameters=m.getParameters();
                    for(int i=0;i<parameters.length;i++){
                        if(parameters[i].isAnnotationPresent(Validate.class)){
                            Validate validate=parameters[i].getAnnotation(Validate.class);
                            Object arg=args[i];
                            if (arg instanceof  Double){
                                Double value=(Double)arg;
                                if (validate.notEmpty()&&value==null){
                                    throw  new ValidationException("Parameter cannot be null");
                                }
                                if(!Double.isInfinite(validate.minValue()) &&value <validate.minValue()){
                                    throw  new ValidationException("Parameter value is to low: "+value);
                                }
                                if (!Double.isInfinite(value)&&value > validate.maxValue()){
                                    throw  new ValidationException("Parameter value is to high: "+value);
                                }
                            }else {
                                throw  new IllegalArgumentException("Unsupported parameter type: : "+arg.getClass().getName());
                            }
                        }
                    }
                }
            }
            return method.invoke(target, args);
        }
    }
}
